#ifndef BASE
#define BASE


typedef int Number;

typedef Number* ptrNumber;

class cRange{
public:
	int begin,end;
	cRange(const int& _begin, const int& _end):
		begin(_begin),
		end(_end)
	{};
	friend bool operator>(const cRange& what,const cRange& what2){
		if(what.begin<what2.begin) return false;
		if(what.begin>what2.begin) return true;
		if (what.end>what2.end) return true;
		return false;
	}
	friend bool operator<(const cRange& what,const cRange& what2){
		if(what.begin>what2.begin) return false;
		if(what.begin<what2.begin) return true;
		if (what.end<what2.end) return true;
		return false;
	}
	cRange(){};
	bool operator==(const cRange&what){
		if (begin==what.begin && end==what.end) return true;
		return false;
	}
};

template<class Type> class cList;

//Text:
#include <string>
using namespace std;

typedef string cText;
/*
class cText : public string{
public:
	cText(cText* what, cRange range):
		string(*what,range.begin,range.end-range.begin+1)
	{};
	cText(string& what):
		string(what)
	{};
};
*/
typedef cText* ptrText;


//Set:
#include <set>
using namespace std;

template<class Type> class cSet : public set<Type, less<Type>>{
public:
	typedef set<Type, less<Type>> STLset;
	typedef typename set<Type, less<Type>>::iterator iterator;

	void push(Type what){
		insert(what);
	}

	int length(){
		return size();
	}
};


template<class Tmaster, class Tslave> class cPair;

/////////////////////////////////////////////
#include <map>
using namespace std;

template<class Tkey, class Tvalue>
	class cMapPair:public multimap<Tkey,Tvalue>
{
public:
	//using namespace stdext;
	
	typedef multimap<Tkey,Tvalue> STLmap;
	
	//STLmap storage;
	typedef typename STLmap::iterator iter;


	void push(Tkey key, Tvalue value){
		STLmap::insert(STLmap::value_type(key,value));
	}

	int length(){
		return STLmap::size();
	}
	
	cList<Tvalue>* search(Tkey key){
		pair<STLmap::iterator, STLmap::iterator> p=equal_range(key);
		cList<Tvalue>* ret=new cList<Tvalue>();
		iter i;
		for (i=p.first;i!=p.second;++i)
			ret->push(i->second);
		return ret;
	}

	Tvalue& locate(Tkey key){
		iter=storage.find(key);
		if(iter!=storage.end())
			return (iter->second);
	}
};

template<class Tkey, class Tvalue>
	class cMapUniqueKey
{
public:
	//using namespace stdext;
	
	typedef map<Tkey,Tvalue> STLmap;
	
	STLmap storage;
	typename STLmap::iterator iter;

	void push(Tkey key, Tvalue value){
		storage.insert(STLmap::value_type(key,value));
	}
	
	Tvalue* search(Tkey key){
		iter=storage.find(key);
		if(iter!=storage.end())
			return &(iter->second);
		else
			return NULL;
	}

	Tvalue& locate(Tkey key){
		iter=storage.find(key);
		if(iter!=storage.end())
			return (iter->second);
	}
};
	
#include <hash_map>

using namespace stdext;
struct StrLess : public binary_function<string, string, bool>{
public:
	result_type operator()(const first_argument_type& _Left, const second_argument_type& _Right) const{
		return(_Left.compare(_Right) < 0 ? true : false);
	}
};

template<typename Tvalue> 
	class StrHashmap : 
		public hash_map<
			string,
			Tvalue,
			hash_compare<string, StrLess> 
		>
	{
	public:
		typedef hash_map<string,Tvalue,hash_compare<string, StrLess>> HashType;

		void push(const string& location, Tvalue what){
			this->operator[](location)=what;
		}

		Tvalue* search(const string& what){
			HashType::iterator iter;
			iter=this->find(what);
			if (iter==this->end()){
				return NULL;
			}
			else return &(iter->second);
		}
	};
	


template<class Type> 
	class cArray : 
		public hash_map<int,Type>
	{
	public:
		void push(int location, Type what){
			this->operator[](location)=what;
		}

		Type search(int what){
			return this->operator[](what);
		}
	};

//class cMultiKeys;
//class cUniqueMultiKeys

template<class Type> class cList : public vector<Type>{
public:
	Number length(){
		return size();
	}

	void push(const Type& what){
		vector<Type>::push_back(what);
	}

	void pop(){
		vector<Type>::pop_back();
	}
};



#endif